import { _decorator, color, director, System } from 'cc';
import { BaseManager } from './../libs/rxjs/cc3/BaseManager';
import { LoadingPanelMode } from './Enums';
import { GameKey } from './SubgameConfig';
import { ReactiveProperty } from './../libs/rxjs/cc3/ReactiveProperty';
import { ReactiveCommand } from '../libs/rxjs/cc3/ReactiveCommand';
import { KeyDownUp } from '../libs/rxjs/cc3/KeyEvent';
import { EventKeyboard } from 'cc';
import { KeyCode } from 'cc';
import { Interval } from '../libs/rxjs/cc3/CreatorSchedule';
import { StringTools } from '../libs/utils/StringTools';
import { appsflyer_sdk_m } from './SDK/AppsFlyerSDKManager';
import { jsb_sdk_m } from './SDK/JsbSDKManager';
import { game } from 'cc';
import { sys } from 'cc';
import { ReactiveSet } from '../libs/rxjs/cc3/ReactiveSet';

// 跨包引用，只有在lobby包加载后才能使用声明的对象
import { StageInfo } from '../../ab_lobby/scripts/game/basic';
import { StageView } from '../../ab_lobby/scripts/ui/GamePanel/2d/StageView';

const { ccclass, property } = _decorator;

@ccclass('GameManager')
class GameManager extends BaseManager {

    public static instance: GameManager;
    static ID = 'game_system';
    get logColorOverride() { return color().fromHEX('#EEDDCC') };

    static registerSystem() {
        director.unregisterSystem(director.getSystem(GameManager.ID));
        director.registerSystem(GameManager.ID, gm, System.Priority.MEDIUM);
        gm.init();
    }

    loadingPanelMode = LoadingPanelMode.FirstTime;
    maxProgressValue = 100;
    curProgressValue = ReactiveProperty.Create(0);
    curProgressValue2 = ReactiveProperty.Create(0);

    loadingAssets = ReactiveProperty.Create(true);
    wsConnected = ReactiveProperty.Create(false);

    curSubgame = ReactiveProperty.Create<GameKey>(null);

    fullScreenChangedCommand = ReactiveCommand.Create();

    editAltPressed = ReactiveProperty.Create(false);
    editShiftPressed = ReactiveProperty.Create(false);
    editCtrlPressed = ReactiveProperty.Create(false);

    stageInfo = ReactiveProperty.Create<StageInfo>(null);

    stageView: StageView = null;

    saveStageCommand = ReactiveCommand.Create<number>();
    loadStageCommand = ReactiveCommand.Create<number | StageInfo>();
    stageInfoChanged = ReactiveCommand.Create<StageInfo>();

    loadGameCommand = ReactiveCommand.Create();
    loadNextGameCommand = ReactiveCommand.Create();

    isWin = ReactiveProperty.Create(false);
    isLose = ReactiveProperty.Create(false);
    pauseReason = ReactiveSet.Create<string>();
    stageStartAt = ReactiveProperty.Create(0); // 关卡开始时刻
    curTime = ReactiveProperty.Create(0); // 关卡当前时间

    inAnimation = ReactiveProperty.Create(false);

    swapperSelected = ReactiveProperty.Create(false); // 交换道具选中
    swapperSelectedIdx = ReactiveProperty.Create<number>(null); // 交换器选择的第一个位置
    balloonSelected = ReactiveProperty.Create(false); // 气球道具选中
    magnetSelected = ReactiveProperty.Create(false); // 磁铁点击(无状态)

    continueCount = ReactiveProperty.Create(0); // 当前关卡花金币继续的次数

    heartAnimatingFlags = ReactiveSet.Create<string>();
    coinAnimatingFlags = ReactiveSet.Create<string>();
    itemAnimatingFlags = ReactiveSet.Create<string>();

    lobbyScrollToShopCommand = ReactiveCommand.Create();

    diffX2 = ReactiveProperty.Create(0);

    myLeaderboardItemHide = ReactiveProperty.Create(false);

    lastWinStageNum = ReactiveProperty.Create<number>(null);

    openWaitingPlaceCommand = ReactiveCommand.Create<number>();

    // editor
    // inEditMode = ReactiveProperty.Create<boolean>(null);

    editEnabled = ReactiveProperty.Create(false);

    editPosSelected = ReactiveProperty.Create<number>(null);
    editColorSelected = ReactiveProperty.Create<number>(null);
    editToolsSelected = ReactiveProperty.Create<string>(null); // 当前编辑器选中的工具

    unfocusAllCommand = ReactiveCommand.Create<string>(); // 取消焦点命令

    glassesInfoRefreshCommand = ReactiveCommand.Create(); // 刷新玻璃命令

    // statistics
    // itemUseTimes_frozen = ReactiveProperty.Create(0);
    // itemUseTimes_hammer = ReactiveProperty.Create(0);
    itemUseTimes_Swapper = ReactiveProperty.Create(0);
    itemUseTimes_Magnet = ReactiveProperty.Create(0);
    itemUseTimes_Balloon = ReactiveProperty.Create(0);

    completed_progress_map = ReactiveProperty.Create<Map<number, number>>(new Map());

    currentLevelType = ReactiveProperty.Create('New');
    reviveTimes = ReactiveProperty.Create(0); // 本局复活次数
    // addTime = ReactiveProperty.Create(0); // 本局已增加时长（秒）（计算复活和时间冻结道具增加的时长）
    coinUse = ReactiveProperty.Create(0); // 本局消耗金币 复活，购买道具
    losePopupReason = ReactiveProperty.Create(null); // 失败原因

    currentAdsType = ReactiveProperty.Create<string>(null);
    currentAdsOpenUI = ReactiveProperty.Create<string>(null);

    currentInterstitialAdsType = ReactiveProperty.Create<string>(null); // 插屏广告类型

    winStageInfo = ReactiveProperty.Create<StageInfo>(null); // 胜利时，缓存胜利关卡的stageInfo

    interstitialAdLoadFailed = ReactiveProperty.Create(true); // 插屏上次加载失败
    rewardedAdLoadFailed = ReactiveProperty.Create(true); // 激励上次加载失败
    bannerAdLoadFailed = ReactiveProperty.Create(true); // banner上次加载失败

    interstitialAdDidHide = ReactiveCommand.Create(); // 插屏广告关闭时

    // cheat
    forceWinCommand = ReactiveCommand.Create(); // 强制胜利
    forceLoseCommand = ReactiveCommand.Create(); // 强制失败

    gameHudHide = ReactiveProperty.Create(false); // 游戏hud隐藏（为了宣发资料）

    willBind(): void {
        globalThis.dev = StringTools.getValueInSearch('dev') == '1';
        this.editEnabled.value = StringTools.getValueInSearch('edit') == '1';
    }

    useObserves() {
        return [
            KeyDownUp().subscribe((_: EventKeyboard) => {
                if (_.keyCode == KeyCode.ALT_LEFT) {
                    this.editAltPressed.value = _.isPressed;
                } else if (_.keyCode == KeyCode.SHIFT_LEFT) {
                    this.editShiftPressed.value = _.isPressed;
                } else if (_.keyCode == KeyCode.CTRL_LEFT) {
                    this.editCtrlPressed.value = _.isPressed;
                }
            }),

            Interval(1).subscribe(this.timerStep.bind(this)),
            Interval(60).subscribe(_ => jsb_sdk_m.storeLaunchTime()),
        ];
    }

    onInitManager(): void {
        if (sys.isNative) game.frameRate = 59;
        // Timer(1).subscribe(_ => {
        //     MouseDownUp().subscribe((_: EventMouse) => {
        //         this.log('eventMouse', _);
        //     })
        // });
    }

    timerStep() {
        appsflyer_sdk_m.check_af_r30r();
    }
}

globalThis.GameManager = GameManager;

export const gm = GameManager.instance = new GameManager();
